package org.examples;

import java.io.IOException;
import java.net.URI;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.util.Set;

import org.apache.hc.core5.http.HttpException;
import org.apache.hc.core5.http.HttpHost;
import org.apache.hc.core5.http.HttpRequest;
import org.apache.hc.core5.http.Method;
import org.apache.hc.core5.http.message.BasicHttpRequest;
import org.apache.hc.core5.http.nio.AsyncEntityProducer;
import org.apache.hc.core5.http.nio.AsyncRequestProducer;
import org.apache.hc.core5.http.nio.DataStreamChannel;
import org.apache.hc.core5.http.nio.RequestChannel;
import org.apache.hc.core5.http.protocol.HttpContext;

public class VocsAsyncRequestProducer implements AsyncRequestProducer {

  private HttpRequest request = null;

  private static String reqS1 = "--x5Ek-_yVTvKyrijAacB5k13MeM0koYgwg9uYs\n"
      + "Content-Disposition: form-data; name=\"Input\"\n"
      + "Content-Type: application/json; charset=UTF-8\r\n\r\n";

  private static String reqS2 =
      "{\"data\": \"The result will be millions of Americans who have insurance who did not have it before.Thats the goal. And the goal is not about the website.\", \"content_type\": \"text/plain;charset=iso8859-1\", \"content_encoding\": \"8bit\"}\n"
          + "--x5Ek-_yVTvKyrijAacB5k13MeM0koYgwg9uYs\n"
          + "Content-Disposition: form-data; name=\"Parameters\"\n"
          + "Content-Type: application/json; charset=UTF-8\r\n\r\n";

  private static String reqS3 =
      "{\"language\": \"en-us\", \"voice\": \"zoe-ml\", \"volume\": \"80\", \"audio_chunk_duration_ms\": \"20000\", \"sample_rate\": \"16000\", \"output_type\": \"10\", \"rate\": \"50\", \"session_id\": \"e73db992-5301-4a85-b333-2b4e77e9db81\"}\n"
          + "--x5Ek-_yVTvKyrijAacB5k13MeM0koYgwg9uYs--\r\n";

  private ByteBuffer buf1 = ByteBuffer.wrap(reqS1.getBytes(Charset.forName("ISO-8859-1")));

  private ByteBuffer buf2 = ByteBuffer.wrap(reqS2.getBytes(Charset.forName("ISO-8859-1")));

  private ByteBuffer buf3 = ByteBuffer.wrap(reqS3.getBytes(Charset.forName("ISO-8859-1")));

  private AsyncEntityProducer dataProducer = new AsyncEntityProducer() {
    @Override
    public boolean isRepeatable() {
      return false;
    }

    @Override
    public void failed(Exception e) {

    }

    @Override
    public long getContentLength() {
      return buf1.remaining() + buf2.remaining() + buf3.remaining();
    }

    @Override
    public String getContentType() {
      return "multipart/form-data; charset=ISO-8859-1; boundary=x5Ek-_yVTvKyrijAacB5k13MeM0koYgwg9uYs";
    }

    @Override
    public String getContentEncoding() {
      return null;
    }

    @Override
    public boolean isChunked() {
      return false;
    }

    @Override
    public Set<String> getTrailerNames() {
      return null;
    }

    @Override
    public int available() {
      return 0;
    }

    @Override
    public void produce(DataStreamChannel dataStreamChannel) throws IOException {

    }

    @Override
    public void releaseResources() {

    }
  };

  public VocsAsyncRequestProducer() {
//        this.request = new BasicHttpRequest("POST", new HttpHost("10.192.128.28",28166) , "/vocs/speak");
    this.request = new BasicHttpRequest("POST", new HttpHost("47.108.196.76", 8080), "/post");
    this.dataProducer = dataProducer;
  }

  @Override
  public void sendRequest(final RequestChannel requestChannel, final HttpContext httpContext) throws HttpException, IOException {
    requestChannel.sendRequest(request, dataProducer, httpContext);
  }

  @Override
  public int available() {
    return dataProducer != null ? dataProducer.available() : 0;
  }

  @Override
  public void produce(final DataStreamChannel channel) throws IOException {
    channel.write(buf1);
//    channel.write(ByteBuffer.wrap("\r\n\r\n".getBytes(Charset.defaultCharset())));
    channel.write(buf2);
//    channel.write(ByteBuffer.wrap("\r\n\r\n".getBytes(Charset.defaultCharset())));
    channel.write(buf3);
//    channel.write(ByteBuffer.wrap("\r\n".getBytes(Charset.defaultCharset())));
    channel.endStream();
  }

  @Override
  public boolean isRepeatable() {
    return dataProducer == null || dataProducer.isRepeatable();
  }

  @Override
  public void failed(final Exception cause) {
    try {
      if (dataProducer != null) {
        dataProducer.failed(cause);
      }
    } finally {
      releaseResources();
    }
  }

  @Override
  public void releaseResources() {
    if (dataProducer != null) {
      dataProducer.releaseResources();
    }
  }
}
